import { type NitroFetchRequest } from 'nitropack'
import { omitBy, pick } from 'lodash-es'
import type { FetchResponse, FetchContext, ResponseType } from 'ofetch'
import { showFailToast } from 'vant'
import objectHash from 'object-hash'
import type { NuxtApp } from '#app'
import { TT } from './token'
import { useGlobalStore } from '~/store'
import type { ApiResponse } from '~/types/global'

export function transformResponse(input: any) {
  if (input.timestamp) {
    return input
  }
  return {
    ...input,
    timestamp: new Date(),
  }
}

export function getCachedData(key: string, nuxtApp: NuxtApp, cacheTime: number = 30) {
  const data = nuxtApp.static.data[key] ?? nuxtApp.payload.data[key]
  if (!data) {
    return
  }
  const expirationDate = new Date(data.timestamp)
  expirationDate.setTime(expirationDate.getTime() + cacheTime * 1000)
  const isExpired = expirationDate.getTime() < Date.now()
  if (isExpired) {
    return
  }
  return data
}

export function getHashByOptions<T = unknown, R extends NitroFetchRequest = NitroFetchRequest>(
  request: Parameters<typeof $fetch<T, R>>[0],
  options?: Partial<Parameters<typeof $fetch<T, R>>[1]>,
): string {
  const hashObj = Object.assign(pick(options, ['query', 'params', 'body']), { request })
  const hash = objectHash(hashObj)
  return hash
}

export const getHeader = (): HeadersInit => {
  //   const token = `useCookie('token')`
  let token: string | null | undefined
  if (import.meta.server) {
    token = useCookie('token').value
  } else {
    const globalStore = useGlobalStore()
    token = globalStore.token
  }
  token = TT
  return omitBy(
    {
      Authorization: token ? `Bearer ${token}` : undefined,
    },
    (v) => v === undefined || v === null,
  ) as unknown as HeadersInit
}

export const onRequest = (context: FetchContext<any, ResponseType>) => {
  context.options.headers = {
    ...context.options.headers,
    ...getHeader(),
  }
}

export const onResponse = (
  context: FetchContext & {
    response: FetchResponse<ResponseType>
  },
) => {
  const data: ApiResponse<any> = context.response._data
  if (!data.timestamp) {
    data.timestamp = new Date()
  }
}

export const clearAuth = () => {
  const globalStore = useGlobalStore()
  globalStore.$reset()
}

export const onResponseError = (
  context: FetchContext & {
    response: FetchResponse<ResponseType>
  },
) => {
  // const data: ApiResponse<null> = context.response._data
  // console.info('status', context.response.status)
  const handleMap: { [key: number]: () => void } = {
    401: () => showFailToast(context.response._data.message),
    404: () => showFailToast('服务器资源不存在'),
    500: () => showFailToast('服务器内部错误'),
    403: () => showFailToast('没有权限访问该资源'),
  }
  handleMap[context.response.status]?.()

  console.log('onResponseError', context)

  if (context.response.status === 401) {
    clearAuth()
    navigateTo('/login')
  }
}
